home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / editor / j414src.arc / SCANDIR.C < prev    next >
C/C++ Source or Header  |  1989-10-10  |  5KB  |  221 lines

  1. /***************************************************************************
  2.  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  3.  * is provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is    *
  5.  * included in all the files.                                              *
  6.  ***************************************************************************/
  7.  
  8. #include "jove.h"
  9. #include "scandir.h"
  10.  
  11. #ifdef F_COMPLETION
  12.  
  13. #ifdef MSDOS
  14. # include <dos.h>
  15. # include <search.h>
  16. #endif
  17.  
  18. #ifdef UNIX
  19. # include <sys/stat.h>
  20. # ifdef M_XENIX
  21. #  include <sys/ndir.h>
  22. # else
  23. #  include <sys/dir.h>
  24. # endif /* M_XENIX */
  25. #endif
  26.  
  27. #ifdef UNIX
  28.  
  29. #ifdef mips
  30. # undef scandir
  31. #endif
  32.  
  33. #ifdef BSD_DIR
  34. # define DIRSIZE(entry)    DIRSIZ((entry))
  35. #else
  36. # define DIRSIZE(entry)    ((entry)->d_name[DIRSIZ-1]=='\0' ? strlen((entry)->d_name) : DIRSIZ)
  37.  
  38. typedef struct {
  39.     int    d_fd;        /* File descriptor for this directory */
  40. } DIR;
  41.  
  42. DIR *
  43. opendir(dir)
  44. char    *dir;
  45. {
  46.     DIR    *dp = (DIR *) malloc(sizeof *dp);
  47.     struct stat    stbuf;
  48.  
  49.     if ((dp->d_fd = open(dir, 0)) == -1)
  50.         return 0;
  51.     if ((fstat(dp->d_fd, &stbuf) == -1) || !(stbuf.st_mode & S_IFDIR)) {
  52.         closedir(dp);
  53.         return 0;    /* this isn't a directory! */
  54.     }
  55.     return dp;
  56. }
  57.  
  58. closedir(dp)
  59. DIR    *dp;
  60. {
  61.     (void) close(dp->d_fd);
  62.     free((char *) dp);
  63. }
  64.  
  65. struct direct *
  66. readdir(dp)
  67. DIR    *dp;
  68. {
  69.     static struct direct    dir;
  70.  
  71.     do
  72.         if (read(dp->d_fd, &dir, sizeof dir) != sizeof dir)
  73.             return 0;
  74. #if defined(elxsi) && defined(SYSV)
  75.     /*
  76.      * Elxsi has a BSD4.2 implementation which may or may not use
  77.      * `twisted inodes' ...  Anyone able to check?
  78.      */
  79.     while (*(unsigned short *)&dir.d_ino == 0);
  80. #else
  81.     while (dir.d_ino == 0);
  82. #endif
  83.  
  84.     return &dir;
  85. }
  86.  
  87. #endif /* BSD_DIR */
  88.  
  89. /* Scandir returns the number of entries or -1 if the directory cannoot
  90.    be opened or malloc fails. */
  91.  
  92. int
  93. scandir(dir, nmptr, qualify, sorter)
  94. char    *dir;
  95. char    ***nmptr;
  96. int    (*qualify) proto((char *));
  97. int    (*sorter) proto((UnivConstPtr, UnivConstPtr));
  98. {
  99.     DIR    *dirp;
  100.     struct direct    *entry;
  101.     char    **ourarray;
  102.     unsigned int    nalloc = 10,
  103.             nentries = 0;
  104.  
  105.     if ((dirp = opendir(dir)) == 0)
  106.         return -1;
  107.     if ((ourarray = (char **) malloc(nalloc * sizeof (char *))) == 0)
  108. memfail:    complain("[Malloc failed: cannot scandir]");
  109.     while ((entry = readdir(dirp)) != 0) {
  110.         if (qualify != 0 && (*qualify)(entry->d_name) == 0)
  111.             continue;
  112.         if (nentries == nalloc) {
  113.             ourarray = (char **) realloc((char *) ourarray, (nalloc += 10) * sizeof (char *));
  114.             if (ourarray == 0)
  115.                 goto memfail;
  116.         }
  117.         ourarray[nentries] = (char *) malloc(DIRSIZE(entry) + 1);
  118.         null_ncpy(ourarray[nentries], entry->d_name, (size_t) DIRSIZE(entry));
  119.         nentries += 1;
  120.     }
  121.     closedir(dirp);
  122.     if ((nentries + 1) != nalloc)
  123.         ourarray = (char **) realloc((char *) ourarray,
  124.                     ((nentries + 1) * sizeof (char *)));
  125.     if (sorter != 0)
  126.         qsort((char *) ourarray, nentries, sizeof (char **), sorter);
  127.     *nmptr = ourarray;
  128.     ourarray[nentries] = 0;        /* guaranteed 0 pointer */
  129.  
  130.     return nentries;
  131. }
  132.  
  133. #endif /* UNIX */
  134.  
  135. #ifdef MSDOS
  136. # define DIRSIZ    13
  137. # define DIRSIZE(entry)    strlen((entry).name)
  138.  
  139. /* Scandir returns the number of entries or -1 if the directory cannot
  140.    be opened or malloc fails. */
  141.  
  142. unsigned int fmask = _A_NORMAL|_A_RDONLY|_A_HIDDEN|_A_SUBDIR;
  143.  
  144. int
  145. scandir(dir, nmptr, qualify, sorter)
  146. char    *dir;
  147. char    ***nmptr;
  148. int    (*qualify) proto((char *));
  149. int    (*sorter) proto((UnivConstPtr, UnivConstPtr));
  150. {
  151.     char dirname[FILESIZE];
  152.     struct find_t entry;
  153.     char *ptr;
  154.     char    **ourarray;
  155.     unsigned int    nalloc = 10,
  156.             nentries = 0;
  157.  
  158.     strcpy(dirname, dir);
  159.     ptr = &dirname[strlen(dirname)-1];
  160.     if ((dirname[1] == ':' && !dirname[2]) || (*ptr == '/') || (*ptr == '\\'))
  161.        strcat(dirname, "*.*");
  162.     else
  163.        strcat(dirname, "/*.*");
  164.  
  165.     if (_dos_findfirst(dirname, fmask, &entry))
  166.        return -1;
  167.     if ((ourarray = (char **) malloc(nalloc * sizeof (char *))) == 0)
  168. memfail:    complain("[Malloc failed: cannot scandir]");
  169.     do  {
  170.         if ((fmask == 0x10) && !(entry.attrib&fmask))
  171.             goto skip;
  172.         strlwr(entry.name);
  173.         if (qualify != (int (*)())0 && (*qualify)(entry.name) == 0)
  174.             goto skip;
  175.         if (nentries == nalloc) {
  176.             ourarray = (char **) realloc((char *) ourarray, (nalloc += 10) * sizeof (char *));
  177.             if (ourarray == 0)
  178.                 goto memfail;
  179.         }
  180.         ourarray[nentries] = (char *) malloc(DIRSIZE(entry) + 1);
  181.         null_ncpy(ourarray[nentries], entry.name, (int) DIRSIZE(entry));
  182.         nentries++;
  183. skip:    ;
  184.     }
  185.     while (_dos_findnext(&entry) == 0);
  186.  
  187.     if ((nentries + 1) != nalloc)
  188.         ourarray = (char **) realloc((char *) ourarray,
  189.                     ((nentries + 1) * sizeof (char *)));
  190.     if (sorter != (int (*)())0)
  191.         qsort((char *) ourarray, nentries, sizeof (char **), sorter);
  192.     *nmptr = ourarray;
  193.     ourarray[nentries] = 0;        /* guaranteed 0 pointer */
  194.  
  195.     return nentries;
  196. }
  197.  
  198. #endif /* MSDOS */
  199.  
  200. void
  201. freedir(nmptr, nentries)
  202. char    ***nmptr;
  203. int    nentries;
  204. {
  205.     char    **ourarray = *nmptr;
  206.  
  207.     while (--nentries >= 0)
  208.         free(*ourarray++);
  209.     free((char *) *nmptr);
  210.     *nmptr = 0;
  211. }
  212.  
  213. int
  214. alphacomp(a, b)
  215. UnivConstPtr    a,
  216.     b;
  217. {
  218.     return strcmp(*(const char **)a, *(const char **)b);
  219. }
  220. #endif
  221.